﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System;
using System.Globalization;

namespace Tesla.Graphics {
    /// <summary>
    /// Description for a display mode.
    /// </summary>
    public struct DisplayMode : IEquatable<DisplayMode> {
        private int _width;
        private int _height;
        private SurfaceFormat _format;

        /// <summary>
        /// Gets the display width in pixels.
        /// </summary>
        public int Width {
            get {
                return _width;
            }
        }

        /// <summary>
        /// Gets the display height in pixels.
        /// </summary>
        public int Height {
            get {
                return _height;
            }
        }

        /// <summary>
        /// Gets the aspect ratio (width / height).
        /// </summary>
        public float AspectRatio {
            get {
                if(_width != 0 && _height != 0) {
                    return (float) _width / (float) _height;
                }
                return 0.0f;
            }
        }

        /// <summary>
        /// Gets the surface format supported by this display mode.
        /// </summary>
        public SurfaceFormat SurfaceFormat {
            get {
                return _format;
            }
        }

        /// <summary>
        /// Creates a new display mode description.
        /// </summary>
        /// <param name="width">Width of the display in pixels</param>
        /// <param name="height">Height of the display in pixels</param>
        /// <param name="format">Format of the display</param>
        public DisplayMode(int width, int height, SurfaceFormat format) {
            _width = width;
            _height = height;
            _format = format;
        }

        /// <summary>
        /// String representation of DisplayMode
        /// </summary>
        /// <returns>String representation</returns>
        public override string ToString() {
            return String.Format(CultureInfo.CurrentCulture, "{{Width: {0}, Height: {1}, AspectRatio: {2}, SurfaceFormat: {3}}}", new Object[] { _width, _height, AspectRatio, _format });
        }

        /// <summary>
        /// Equality test between this DisplayMode and another.
        /// </summary>
        /// <param name="other">Other display mode</param>
        /// <returns>True if equal</returns>
        public bool Equals(DisplayMode other) {
            return _format == other.SurfaceFormat && _width == other.Width && _height == other.Height;
        }

        /// <summary>
        /// Equality test between this DisplayMode and an object.
        /// </summary>
        /// <param name="obj">Other object</param>
        /// <returns>True if the object is a DisplayMode and is equal, false if otherwise</returns>
        public override bool Equals(Object obj) {
            if(obj is DisplayMode) {
                DisplayMode other = (DisplayMode) obj;
                return _format == other.SurfaceFormat && _width == other.Width && _height == other.Height;
            }
            return false;
        }

        /// <summary>
        /// Equality operator.
        /// </summary>
        /// <param name="a">First DisplayMode</param>
        /// <param name="b">Second DisplayMode</param>
        /// <returns>True if equal</returns>
        public static bool operator==(DisplayMode a, DisplayMode b) {
            return a.SurfaceFormat == b.SurfaceFormat && a.Width == b.Width && a.Height == b.Height;
        }

        /// <summary>
        /// Inequality operator.
        /// </summary>
        /// <param name="a">First DisplayMode</param>
        /// <param name="b">Second DisplayMode</param>
        /// <returns>True if not equal</returns>
        public static bool operator!=(DisplayMode a, DisplayMode b) {
            return a.SurfaceFormat != b.SurfaceFormat || a.Width != b.Width || a.Height != b.Height;
        }

        /// <summary>
        /// Hashcode override.
        /// </summary>
        /// <returns>hash code</returns>
        public override int GetHashCode() {
            return Width.GetHashCode() + Height.GetHashCode() + SurfaceFormat.GetHashCode();
        }
    }
}
